<template>
  <el-dialog
    v-model="dialogVisible"
    :title="t('upload.dialog.title')"
    width="600px"
    :close-on-click-modal="false"
    :before-close="handleCancel"
    destroy-on-close
  >
    <div class="report-image-config">
      <!-- 检查项目选择 -->
      <div v-if="isFrom === 'reportImage'" class="config-item">
        <label class="config-label">检查项目</label>
        <el-select
          v-model="medicalType"
          placeholder="请选择检查项目"
          clearable
          style="width: 220px"
        >
          <el-option
            v-for="item in medicalTypeList"
            :key="item.id"
            :label="item.name"
            :value="item.id"
          />
        </el-select>
      </div>

      <!-- 影像类型选择 -->
      <div
        v-if="isFrom === 'reportImage' || isFrom === 'film'"
        class="config-item"
      >
        <label class="config-label">影像类型</label>
        <el-radio-group v-model="imageType" class="image-type-group">
          <el-radio value="1" size="default"> 影像图片 </el-radio>
          <el-radio value="2" size="default"> 影像二维码 </el-radio>
        </el-radio-group>
      </div>
    </div>

    <!-- 上传区域 -->
    <div
      v-if="!showUploadProgress || fileList.length === 0"
      class="upload-area"
    >
      <el-upload
        ref="uploadRef"
        v-model:file-list="fileList"
        class="upload-dragger"
        :auto-upload="false"
        :multiple="multiple"
        :accept="accept"
        :before-upload="handleBeforeUpload"
        :on-change="handleFileChange"
        :show-file-list="false"
      >
        <div class="upload-content">
          <div class="upload-icon">
            <svg width="64" height="64" viewBox="0 0 64 64" fill="none">
              <rect width="64" height="64" rx="8" fill="#E3F2FD" />
              <path
                d="M20 44V20C20 18.8954 20.8954 18 22 18H32L42 28V44C42 45.1046 41.1046 46 40 46H22C20.8954 46 20 45.1046 20 44Z"
                fill="#2196F3"
              />
              <path
                d="M32 18V28H42"
                stroke="#1976D2"
                stroke-width="2"
                stroke-linejoin="round"
              />
              <path
                d="M26 34H36M26 38H34"
                stroke="white"
                stroke-width="2"
                stroke-linecap="round"
              />
            </svg>
          </div>
          <div class="upload-text">
            <p class="main-text">{{ t("upload.uploadArea.dragText") }}</p>
            <div class="upload-tips">
              <p v-for="tip in displayTips" :key="tip">• {{ tip }}；</p>
            </div>
          </div>
        </div>
      </el-upload>

      <!-- 选中的文件列表 -->
      <div v-if="fileList.length > 0" class="selected-files">
        <div v-for="file in fileList" :key="file.uid" class="file-item">
          <div class="file-info">
            <div class="file-icon">
              <svg width="24" height="24" viewBox="0 0 24 24" fill="none">
                <path
                  d="M14 2H6C4.9 2 4 2.9 4 4V20C4 21.1 4.89 22 5.99 22H18C19.1 22 20 21.1 20 20V8L14 2Z"
                  fill="#2196F3"
                />
                <path
                  d="M14 2V8H20"
                  stroke="#1976D2"
                  stroke-width="1"
                  fill="none"
                />
              </svg>
            </div>
            <div class="file-details">
              <div class="file-name">{{ file.name }}</div>
              <div class="file-size">{{ formatFileSize(file.size || 0) }}</div>
            </div>
            <div class="file-actions">
              <el-button type="text" size="small" @click="removeFile(file)">
                <el-icon><Close /></el-icon>
              </el-button>
            </div>
          </div>
        </div>
      </div>
    </div>

    <!-- 上传进度区域 -->
    <div v-else class="progress-area">
      <div v-for="file in fileList" :key="file.uid" class="file-item">
        <div class="file-info">
          <div class="file-icon">
            <svg width="24" height="24" viewBox="0 0 24 24" fill="none">
              <path
                d="M14 2H6C4.9 2 4 2.9 4 4V20C4 21.1 4.89 22 5.99 22H18C19.1 22 20 21.1 20 20V8L14 2Z"
                fill="#2196F3"
              />
              <path
                d="M14 2V8H20"
                stroke="#1976D2"
                stroke-width="1"
                fill="none"
              />
            </svg>
          </div>
          <div class="file-details">
            <div class="file-name">{{ file.name }}</div>
            <div v-if="file.status === 'uploading'" class="file-status">
              {{ t("upload.status.uploading") }}
            </div>
            <div
              v-else-if="file.status === 'success'"
              class="file-status success"
            >
              {{ t("upload.status.uploadSuccess") }}
            </div>
            <div v-else-if="file.status === 'fail'" class="file-status error">
              {{ t("upload.status.uploadFailed") }}
            </div>
          </div>
          <div class="file-actions">
            <el-button
              v-if="file.status !== 'success'"
              type="text"
              size="small"
              @click="removeFile(file)"
            >
              <el-icon><Close /></el-icon>
            </el-button>
          </div>
        </div>
        <div v-if="file.status === 'uploading'" class="progress-bar">
          <el-progress
            :percentage="file.percentage || 0"
            :color="progressColor"
            :stroke-width="4"
          />
        </div>
        <div v-else-if="file.status === 'success'" class="progress-bar">
          <el-progress :percentage="100" color="#67C23A" :stroke-width="4" />
        </div>
      </div>
    </div>

    <!-- 底部按钮 -->
    <template #footer>
      <div :class="footerClass">
        <!-- 底部提示 -->
        <div class="upload-notice">{{ t("upload.messages.uploadNotice") }}</div>
        <div>
          <el-button @click="handleCancel">
            {{
              showUploadProgress
                ? t("upload.buttons.previousStep")
                : t("upload.buttons.cancel")
            }}
          </el-button>
          <el-button
            v-if="!showUploadProgress"
            type="primary"
            :disabled="fileList.length === 0"
            @click="handleStartUpload"
          >
            {{ t("upload.buttons.startUpload") }}
          </el-button>
          <el-button
            v-else
            type="primary"
            :disabled="!allFilesUploaded"
            @click="handleComplete"
          >
            {{ countdownText || t("upload.buttons.complete") }}
          </el-button>
        </div>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { useToolsStore } from "@/store/modules/tools";
import {
  generateAccept,
  getFileSizeErrorMessage,
  getFileTypeErrorMessage,
  getFileTypeTips,
  formatFileSize as utilFormatFileSize,
  validateFileSize,
  validateFileType
} from "@/utils/fileTypeConfig";
import { Close } from "@element-plus/icons-vue";
import type { UploadFile, UploadFiles } from "element-plus";
import { ElMessage } from "element-plus";
import { computed, ref, watch } from "vue";
import { useI18n } from "vue-i18n";
const toolsStore = useToolsStore();
const dictData = computed(() => toolsStore.getDictData());
const medicalTypeList = computed(() => dictData.value.medicalTypeList);
// 定义 props
interface Props {
  multiple?: boolean;
  extensions?: string; // 支持的扩展名，如 ".docx,.pdf"
  maxSize?: number; // 自定义最大文件大小(MB)
  limit?: number;
  tips?: string[]; // 自定义提示文本数组
  uploadApi?: (file: File, config?: any) => Promise<any>; // 自定义上传API，支持额外配置参数
  isFrom?: string;
  imageTypeChoose?: string;
  checkItemIdChoose?: number | string;
}

const props = withDefaults(defineProps<Props>(), {
  multiple: true,
  extensions: ".docx,.pdf",
  limit: 10,
  isFrom: "",
  imageTypeChoose: "1",
  checkItemIdChoose: ""
});

// 国际化
const { t, locale } = useI18n();
let medicalType = ref<string | number>("");
let imageType = computed(() => props.imageTypeChoose); //1:影像图片,2:影像二维码

watch(
  () => props.checkItemIdChoose,
  newValue => {
    medicalType.value = newValue;
  },
  { immediate: true }
);

// 存储当前上传的配置参数
const uploadConfig = ref<{
  imageType: string;
  checkItem: string | number;
}>({
  imageType: imageType.value,
  checkItem: ""
});

// 根据语言状态动态调整dialog-footer布局
const footerClass = computed(() => {
  return locale.value === "en"
    ? "dialog-footer dialog-footer--vertical"
    : "dialog-footer";
});

// 计算属性：根据扩展名生成accept
const accept = computed(() => generateAccept(props.extensions));

// 计算属性：优先使用外部传入的tips，否则使用默认生成的tips
const displayTips = computed(() => {
  if (props.tips && props.tips.length > 0) {
    return props.tips;
  }
  return getFileTypeTips(props.extensions, props.maxSize);
});

// 定义 emits
interface UploadSuccessData {
  fileList: UploadFile[];
  checkItem?: string | number;
  imageType?: string;
}

const emit = defineEmits<{
  success: [data: UploadSuccessData];
  cancel: [];
}>();

// 响应式数据
const dialogVisible = ref(false);
const showUploadProgress = ref(false);
const fileList = ref<UploadFiles>([]);
const uploadRef = ref();
const countdown = ref(0);

// 计算属性
const allFilesUploaded = computed(() => {
  return (
    fileList.value.length > 0 &&
    fileList.value.every(file => file.status === "success")
  );
});

const progressColor = computed(() => {
  return [
    { color: "#f56c6c", percentage: 20 },
    { color: "#e6a23c", percentage: 40 },
    { color: "#5cb87a", percentage: 60 },
    { color: "#1989fa", percentage: 80 },
    { color: "#6f7ad3", percentage: 100 }
  ];
});

const countdownText = computed(() => {
  return countdown.value > 0
    ? t("upload.messages.autoCloseCountdown", { seconds: countdown.value })
    : "";
});

// 文件上传前的检查
const handleBeforeUpload = (rawFile: File) => {
  // 检查文件类型
  if (!validateFileType(rawFile, props.extensions)) {
    ElMessage.error(getFileTypeErrorMessage(props.extensions));
    return false;
  }

  // 检查文件大小
  if (!validateFileSize(rawFile, props.extensions, props.maxSize)) {
    ElMessage.error(getFileSizeErrorMessage(props.extensions, props.maxSize));
    return false;
  }

  // 检查文件数量
  if (fileList.value.length >= props.limit) {
    ElMessage.error(t("upload.messages.maxFilesLimit", { limit: props.limit }));
    return false;
  }

  return true;
};

// 文件选择变化
const handleFileChange = (file: UploadFile, files: UploadFiles) => {
  if (file.status === "ready") {
    fileList.value = files;
  }
};

// 使用统一的文件大小格式化函数
const formatFileSize = utilFormatFileSize;

// 移除文件
const removeFile = (file: UploadFile) => {
  const index = fileList.value.findIndex(item => item.uid === file.uid);
  if (index > -1) {
    fileList.value.splice(index, 1);
  }
};

// 开始上传
const handleStartUpload = async () => {
  if (fileList.value.length === 0) {
    ElMessage.warning(t("upload.uploadArea.selectFiles"));
    return;
  }

  // 如果是影像资料上传，保存配置参数
  if (props.isFrom === "reportImage") {
    uploadConfig.value.checkItem = medicalType.value;
    uploadConfig.value.imageType = imageType.value;
    if (!uploadConfig.value.checkItem) {
      ElMessage.error("请选择检查项目");
      return;
    }
    if (!uploadConfig.value.imageType) {
      ElMessage.error("请选择影像类型");
      return;
    }
  }
  if (props.isFrom === "film") {
    uploadConfig.value.imageType = imageType.value;
    if (!uploadConfig.value.imageType) {
      ElMessage.error("请选择影像类型");
      return;
    }
  }

  showUploadProgress.value = true;

  // 逐个上传文件
  for (const file of fileList.value) {
    await uploadFile(file);
  }
};

// 上传单个文件
const uploadFile = async (file: UploadFile): Promise<void> => {
  return new Promise(async resolve => {
    try {
      file.status = "uploading";
      file.percentage = 0;
      // 如果提供了自定义上传API，使用自定义API
      if (props.uploadApi && file.raw) {
        await uploadWithCustomApi(file);
      } else {
        // 否则使用模拟上传
        await simulateUpload(file);
      }

      file.status = "success";
      file.percentage = 100;
      resolve();
    } catch (error) {
      console.error("文件上传失败:", error);
      file.status = "fail";
      ElMessage.error(
        t("upload.messages.uploadFileFailed", { fileName: file.name })
      );
      // resolve(); // 即使失败也继续上传其他文件
    }
  });
};

// 使用自定义API上传
const uploadWithCustomApi = async (file: UploadFile) => {
  if (!props.uploadApi || !file.raw) return;
  // 校验文件类型
  if (!validateFileType(file.raw, props.extensions)) {
    ElMessage.error(getFileTypeErrorMessage(props.extensions));
    throw new Error(getFileTypeErrorMessage(props.extensions));
  }
  // 校验文件大小
  if (!validateFileSize(file.raw, props.extensions, props.maxSize)) {
    ElMessage.error(getFileSizeErrorMessage(props.extensions, props.maxSize));
    throw new Error(getFileSizeErrorMessage(props.extensions, props.maxSize));
  }

  // 检查文件数量
  if (fileList.value.length >= props.limit) {
    ElMessage.error(t("upload.messages.maxFilesLimit", { limit: props.limit }));
    throw new Error(t("upload.messages.maxFilesLimit", { limit: props.limit }));
  }

  // 模拟进度更新
  const progressTimer = setInterval(() => {
    if (file.percentage! < 90) {
      file.percentage = Math.min(file.percentage! + Math.random() * 20, 90);
    }
  }, 200);

  try {
    // 传递文件和配置参数给自定义上传API
    const config =
      props.isFrom === "reportImage" || props.isFrom === "film"
        ? uploadConfig.value
        : undefined;
    console.log("调用自定义上传API，配置参数：", config);
    await props.uploadApi(file.raw, config);
    clearInterval(progressTimer);
    file.percentage = 100;
  } catch (error) {
    clearInterval(progressTimer);
    throw error;
  }
};

// 模拟上传过程
const simulateUpload = (file: UploadFile): Promise<void> => {
  return new Promise(resolve => {
    const timer = setInterval(() => {
      if (file.percentage! < 100) {
        file.percentage = Math.min(file.percentage! + Math.random() * 30, 100);
      } else {
        clearInterval(timer);
        resolve();
      }
    }, 200);
  });
};

// 处理取消/上一步
const handleCancel = () => {
  if (showUploadProgress.value) {
    showUploadProgress.value = false;
  } else {
    dialogVisible.value = false;
    emit("cancel");
  }
};

// 完成上传
const handleComplete = () => {
  // 构建上传成功的数据，确保checkItem和imageType都传递
  const uploadData: UploadSuccessData = {
    fileList: fileList.value
  };

  if (props.isFrom === "reportImage") {
    uploadData.checkItem = medicalType.value;
    uploadData.imageType = imageType.value;
  }
  if (props.isFrom === "film") {
    uploadData.imageType = imageType.value;
  }

  console.log("上传完成，传递的数据:", uploadData);
  emit("success", uploadData);
  dialogVisible.value = false;
  reset();
};

// 重置状态
const reset = () => {
  showUploadProgress.value = false;
  fileList.value = [];
  countdown.value = 0;
  // 重置影像相关配置 - 只有在没有外部传入值时才重置为空
  if (!props.checkItemIdChoose) {
    medicalType.value = "";
  }
  // imageType是computed属性，不需要重置，它会根据props.imageTypeChoose自动更新
  uploadConfig.value.checkItem = "";
  uploadConfig.value.imageType = props.imageTypeChoose;
};

// 监听所有文件上传完成，启动倒计时
watch(allFilesUploaded, newVal => {
  if (newVal && showUploadProgress.value) {
    countdown.value = 3;
    const timer = setInterval(() => {
      countdown.value--;
      if (countdown.value <= 0) {
        clearInterval(timer);
        handleComplete();
      }
    }, 1000);
  }
});

// 打开弹窗
const open = () => {
  dialogVisible.value = true;
  reset();
};

// 暴露方法
defineExpose({
  open
});
</script>

<style lang="scss" scoped>
.report-image-config {
  .config-item {
    display: flex;
    align-items: center;
    margin-bottom: 16px;

    &:last-child {
      margin-bottom: 0;
    }

    .config-label {
      display: inline-block;
      width: 56px;
      font-size: 14px;
      font-weight: 500;
      color: #333333;
      margin-right: 16px;
      text-align: left;
    }

    .image-type-group {
      display: flex;
      gap: 24px;

      :deep(.el-radio) {
        margin-right: 0;
        display: flex;
        align-items: center;

        .el-radio__label {
          display: flex;
          align-items: center;
          font-size: 14px;
          color: #333333;
        }
      }

      .radio-icon {
        font-size: 16px;
        margin-right: 8px;
      }
    }
  }
}

.upload-area {
  padding: 20px 0;

  .selected-files {
    margin-top: 20px;
    padding: 16px;
    border: 1px solid #ebeef5;
    border-radius: 6px;
    background: #fafafa;

    .file-item {
      margin-bottom: 12px;

      &:last-child {
        margin-bottom: 0;
      }

      .file-info {
        display: flex;
        align-items: center;

        .file-icon {
          margin-right: 12px;
        }

        .file-details {
          flex: 1;

          .file-name {
            font-size: 14px;
            color: #303133;
            margin-bottom: 2px;
          }

          .file-size {
            font-size: 12px;
            color: #909399;
          }
        }

        .file-actions {
          .el-button {
            padding: 4px;
          }
        }
      }
    }
  }
}

:deep(.el-upload) {
  width: 100%;
  height: auto;
  min-height: 300px;
  border: 2px solid #dcdfe6;
  border-radius: 8px;
  background: #fafafa;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.3s;
  padding: 10px;
  cursor: pointer;

  &:hover {
    border-color: #409eff;
    background: #f0f9ff;
  }
}

.upload-content {
  display: flex;
  padding: 40px 20px;
  flex-direction: column;
  align-items: center;

  .upload-icon {
    margin-bottom: 20px;
  }

  .upload-text {
    .main-text {
      font-size: 16px;
      color: #303133;
      margin-bottom: 20px;
      font-weight: 500;
      cursor: pointer;
      text-align: center;
    }

    .upload-tips {
      text-align: left;
      color: #909399;
      font-size: 14px;
      line-height: 1.6;

      p {
        margin: 4px 0;
      }
    }
  }
}

.progress-area {
  padding: 20px 0;
  min-height: 200px;
}

.file-item {
  margin-bottom: 16px;
  /* padding: 12px; */
  /* border: 1px solid #ebeef5; */
  /* border-radius: 6px; */
  /* background: #fafafa; */

  .file-info {
    display: flex;
    align-items: center;
    margin-bottom: 8px;

    .file-icon {
      margin-right: 12px;
    }

    .file-details {
      flex: 1;

      .file-name {
        font-size: 14px;
        color: #303133;
        margin-bottom: 4px;
      }

      .file-status {
        font-size: 12px;
        color: #909399;

        &.success {
          color: #67c23a;
        }

        &.error {
          color: #f56c6c;
        }
      }
    }

    .file-actions {
      .el-button {
        padding: 4px;
      }
    }
  }

  .progress-bar {
    margin-top: 8px;
  }
}

.upload-notice {
  color: #909399;
  font-size: 12px;
  white-space: nowrap;
}

.dialog-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;

  &.dialog-footer--vertical {
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;

    .upload-notice {
      order: 2;
    }

    > div:last-child {
      order: 1;
      align-self: flex-end;
    }
  }
}
</style>
